package com.dmbjz.diners.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.dmbjz.common.constant.ApiConstant;
import com.dmbjz.common.model.domain.ResultInfo;
import com.dmbjz.common.model.dto.DinersDTO;
import com.dmbjz.common.model.entity.Diners;
import com.dmbjz.common.model.vo.ShortDinerInfo;
import com.dmbjz.common.utils.AssertUtil;
import com.dmbjz.common.utils.ResultInfoUtil;
import com.dmbjz.diners.config.OAuth2ClintConfiguration;
import com.dmbjz.diners.dao.DinersDao;
import com.dmbjz.diners.entity.OAuthDinerInfo;
import com.dmbjz.diners.entity.vo.LoginDinerInfo;
import com.netflix.discovery.converters.Auto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.LinkedHashMap;
import java.util.List;


/*用户服务业务逻辑层*/
@Service
public class DinersService {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${service.name.ms-oauth-service}")
    private String oauthServiceName;

    @Autowired
    private OAuth2ClintConfiguration oAuth2ClintConfiguration;
    @Autowired
    private DinersDao dinersDao;
    @Autowired
    private SendVerifyCodeService sendVerifyCodeService;


    /*根据 ids集合 查询用户信息*/
    public List<ShortDinerInfo> findByIds(String ids) {
        AssertUtil.isNotEmpty(ids);
        String[] idArr = ids.split(",");
        List<ShortDinerInfo> dinerInfos = dinersDao.findByIds(idArr);
        return dinerInfos;
    }


    /*校验手机号是否已注册*/
    public void checkPhoneIsRegistered(String phone){
        AssertUtil.isNotEmpty(phone,"手机号不能为空!");
        Diners diners = dinersDao.selectByPhone(phone);
        AssertUtil.isTrue(diners==null,"该手机号未注册!");
        AssertUtil.isTrue(diners.getIsValid()==0,"该手机号已被锁定!");
    }

    /*用户注册*/
    public ResultInfo register(DinersDTO dinersDTO,String path){

        /*参数非空校验*/
        AssertUtil.isNotEmpty(dinersDTO.getUsername(),"请输入用户名");
        AssertUtil.isNotEmpty(dinersDTO.getPassword(),"请输入密码");
        AssertUtil.isNotEmpty(dinersDTO.getPhone(),"请输入手机号");
        AssertUtil.isNotEmpty(dinersDTO.getVerifyCode(),"请输入验证码");
        /*获取验证码并验证*/
        String codeByPhone = sendVerifyCodeService.getCodeByPhone(dinersDTO.getPhone());
        AssertUtil.isNotEmpty(codeByPhone,"验证码已过期,请重新获取");
        AssertUtil.isTrue(!codeByPhone.equals(dinersDTO.getVerifyCode()),"验证码不一致,请重新输入");
        /*验证用户是否已注册*/
        Diners diners = dinersDao.selectByUsername(dinersDTO.getUsername());
        AssertUtil.isTrue(diners!=null,"用户名已存在,请重新输入!");
        /*密码加密并保存用户*/
        String password = dinersDTO.getPassword();
        dinersDTO.setPassword(DigestUtil.md5Hex(password));
        dinersDao.saveDiners(dinersDTO);
        /*自动登录*/
        ResultInfo resultInfo = signIn(dinersDTO.getUsername(), password, path);
        return resultInfo;

    }


    /*登录*/
    public ResultInfo signIn(String account,String password,String path){

        /*参数校验*/
        AssertUtil.isNotEmpty(account,"请输入登录账号");
        AssertUtil.isNotEmpty(account,"请输入密码");

        /*构建请求头*/
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        /*构建请求体*/
        MultiValueMap<String,Object> body = new LinkedMultiValueMap<>();
        body.add("username",account);
        body.add("password",password);
        body.setAll(BeanUtil.beanToMap(oAuth2ClintConfiguration));
        HttpEntity<MultiValueMap<String,Object>> entity = new HttpEntity<>(body,headers);

        //设置 Authorization
        restTemplate.getInterceptors().add( new BasicAuthenticationInterceptor(oAuth2ClintConfiguration.getClientId()
                ,oAuth2ClintConfiguration.getSecret()) );

        //发送请求
        ResponseEntity<ResultInfo> result = restTemplate.postForEntity(oauthServiceName + "oauth/token", entity, ResultInfo.class);


        /*处理返回结果*/
        AssertUtil.isTrue(result.getStatusCode()!= HttpStatus.OK,"登录失败");
        ResultInfo resultInfo = result.getBody();
        if(resultInfo.getCode()!= ApiConstant.SUCCESS_CODE){
            resultInfo.setData(resultInfo.getMessage());//状态码不匹配，登录失败
            return resultInfo;
        }
        /*这里的Data是一个 LinkedHashMap 转成域对象 OAuthDinerInfo*/
        OAuthDinerInfo dinerInfo = BeanUtil.fillBeanWithMap((LinkedHashMap) resultInfo.getData(),new OAuthDinerInfo(),false);
        LoginDinerInfo loginDinerInfo = new LoginDinerInfo();
        loginDinerInfo.setToken(dinerInfo.getAccessToken());//设置Token
        loginDinerInfo.setAvatarUrl(dinerInfo.getAvatarUrl());//设置头像
        loginDinerInfo.setNickname(dinerInfo.getNickname());//设置用户名
        return ResultInfoUtil.buildSuccess(path,loginDinerInfo);

    }


}
